// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.iso.sprite;

import java.util.function.Consumer;
import org.lwjgl.opengl.GL11;
import zombie.characters.IsoPlayer;
import zombie.core.Core;
import zombie.core.SpriteRenderer;
import zombie.core.opengl.RenderThread;
import zombie.core.opengl.Shader;
import zombie.core.textures.Texture;
import zombie.core.textures.TextureDraw;
import zombie.input.Mouse;
import zombie.iso.IsoCamera;

public final class IsoCursor {
    private static IsoCursor instance = null;
    IsoCursor.IsoCursorShader m_shader = null;

    public static IsoCursor getInstance() {
        if (instance == null) {
            instance = new IsoCursor();
        }

        return instance;
    }

    private IsoCursor() {
        RenderThread.invokeOnRenderContext(this::createShader);
        if (this.m_shader != null) {
            this.m_shader.m_textureCursor = Texture.getSharedTexture("media/ui/isocursor.png");
        }
    }

    private void createShader() {
        this.m_shader = new IsoCursor.IsoCursorShader();
    }

    public void render(int playerIndex) {
        if (Core.getInstance().getOffscreenBuffer() != null) {
            IsoPlayer isoPlayer = IsoPlayer.players[playerIndex];
            if (isoPlayer != null && !isoPlayer.isDead() && isoPlayer.isAiming() && isoPlayer.PlayerIndex == 0 && isoPlayer.JoypadBind == -1) {
                if (!zombie.GameTime.isGamePaused()) {
                    if (this.m_shader != null && this.m_shader.isCompiled()) {
                        float _float = 1.0F / Core.getInstance().getZoom(playerIndex);
                        int int0 = (int)((float)(this.m_shader.m_textureCursor.getWidth() * Core.TileScale) / 2.0F * _float);
                        int int1 = (int)((float)(this.m_shader.m_textureCursor.getHeight() * Core.TileScale) / 2.0F * _float);
                        this.m_shader.m_screenX = Mouse.getXA() - int0 / 2;
                        this.m_shader.m_screenY = Mouse.getYA() - int1 / 2;
                        this.m_shader.width = int0;
                        this.m_shader.height = int1;
                        int int2 = IsoCamera.getScreenLeft(playerIndex);
                        int int3 = IsoCamera.getScreenTop(playerIndex);
                        int int4 = IsoCamera.getScreenWidth(playerIndex);
                        int int5 = IsoCamera.getScreenHeight(playerIndex);
                        SpriteRenderer.instance.StartShader(this.m_shader.getID(), playerIndex);
                        SpriteRenderer.instance
                            .renderClamped(
                                this.m_shader.m_textureCursor,
                                this.m_shader.m_screenX,
                                this.m_shader.m_screenY,
                                int0,
                                int1,
                                int2,
                                int3,
                                int4,
                                int5,
                                1.0F,
                                1.0F,
                                1.0F,
                                1.0F,
                                this.m_shader
                            );
                        SpriteRenderer.instance.EndShader();
                    }
                }
            }
        }
    }

    private static class IsoCursorShader extends Shader implements Consumer<TextureDraw> {
        private float m_alpha = 1.0F;
        private Texture m_textureCursor;
        private Texture m_textureWorld;
        private int m_screenX;
        private int m_screenY;

        IsoCursorShader() {
            super("isocursor");
        }

        @Override
        public void startMainThread(TextureDraw var1, int _int) {
            this.m_alpha = this.calculateAlpha();
            this.m_textureWorld = Core.getInstance().OffscreenBuffer.getTexture(_int);
        }

        @Override
        public void startRenderThread(TextureDraw var1) {
            this.getProgram().setValue("u_alpha", this.m_alpha);
            this.getProgram().setValue("TextureCursor", this.m_textureCursor, 0);
            this.getProgram().setValue("TextureBackground", this.m_textureWorld, 1);
            SpriteRenderer.ringBuffer.shaderChangedTexture1();
            GL11.glEnable(3042);
        }

        public void accept(TextureDraw textureDraw) {
            byte _byte = 0;
            int int0 = (int)textureDraw.x0 - this.m_screenX;
            int int1 = (int)textureDraw.y0 - this.m_screenY;
            int int2 = this.m_screenX + this.width - (int)textureDraw.x2;
            int int3 = this.m_screenY + this.height - (int)textureDraw.y2;
            this.m_screenX += int0;
            this.m_screenY += int1;
            this.width -= int0 + int2;
            this.height -= int1 + int3;
            float float0 = (float)this.m_textureWorld.getWidthHW();
            float float1 = (float)this.m_textureWorld.getHeightHW();
            float float2 = (float)(IsoCamera.getScreenTop(_byte) + IsoCamera.getScreenHeight(_byte) - (this.m_screenY + this.height));
            textureDraw.tex1 = this.m_textureWorld;
            textureDraw.tex1_u0 = (float)this.m_screenX / float0;
            textureDraw.tex1_v3 = float2 / float1;
            textureDraw.tex1_u1 = (float)(this.m_screenX + this.width) / float0;
            textureDraw.tex1_v2 = float2 / float1;
            textureDraw.tex1_u2 = (float)(this.m_screenX + this.width) / float0;
            textureDraw.tex1_v1 = (float2 + (float)this.height) / float1;
            textureDraw.tex1_u3 = (float)this.m_screenX / float0;
            textureDraw.tex1_v0 = (float2 + (float)this.height) / float1;
        }

        float calculateAlpha() {
            float _float = 0.05F;
            switch (Core.getInstance().getIsoCursorVisibility()) {
                case 0:
                    _float = 0.0F;
                    break;
                case 1:
                    _float = 0.05F;
                    break;
                case 2:
                    _float = 0.1F;
                    break;
                case 3:
                    _float = 0.15F;
                    break;
                case 4:
                    _float = 0.3F;
                    break;
                case 5:
                    _float = 0.5F;
                    break;
                case 6:
                    _float = 0.75F;
            }

            return _float;
        }
    }
}
